#include "W25Q128_sim.h"





/*******************************************************************************
 Description :																			         
 Write data to the device	 														       
 Inputs :																					           
 				Address 	: Write location  										     
 				Size 		: Length in bytes 										     
 				buffer 		: Address where to get the data to write	 
 outputs :																				           
 				"1" 	        : Operation succeeded								       
 Info :																						           
 Note : Mandatory for all types except SRAM and PSRAM			   
********************************************************************************/
int Write(unsigned int Address, unsigned int Size,unsigned char* buffer){
	
  while(Size>256U){
		W25Q_sim_PageProgram(Address-0x90000000U,buffer,256);
		buffer+=256U;
		Size-=256U;
		Address+=256U;
	}
	if(Size){
		W25Q_sim_PageProgram(Address-0x90000000U,buffer,Size);
	}
	W25Q_sim_WaitBusy();

	return 1;
}

/*******************************************************************************
 Description :																			
 Erase a full sector in the device 									
 Inputs :																					  
 				SectrorAddress	: Start of sector 					
 outputs :																				  
 				"1" : Operation succeeded										
 				"0" : Operation failure											
 Note : Not Mandatory for SRAM PSRAM and NOR_FLASH		
********************************************************************************/
int SectorErase(unsigned int EraseStartAddress ,unsigned int EraseEndAddress){
	
	EraseStartAddress = EraseStartAddress - EraseStartAddress%(64U*1024U);
	while (EraseEndAddress>=EraseStartAddress){
		W25Q_sim_64KBErase(EraseStartAddress-0x90000000U);
	  EraseStartAddress += 64U*1024U;
	}
	W25Q_sim_WaitBusy();
	
 	return 1;	
}

/*******************************************************************************
 Description :																			
 Read data from the device	 														
 Inputs :																					
 				Address 	: Write location  										
 				Size 		: Length in bytes 										
 				buffer 		: Address where to get the data to write		
 outputs :																				
 				"1" 		: Operation succeeded								
 				"0" 		: Operation failure										
 Note : Not Mandatory                               
********************************************************************************/	
int Read(unsigned int Address,unsigned int Size,unsigned char* Buffer){     	
	
	W25Q_sim_ReadData(Address-0x90000000U,Buffer,Size);
   
	return 1;     
} 

/*******************************************************************************
 Description :																		
 Verify the data 	 														    
 Inputs :																					
 				MemoryAddr 	: Write location  					
 				RAMBufferAddr 	: RAM Address		          
 				Size 		: Length in bytes 								
 outputs :																				
 				"0" 		: Operation succeeded						
 Note : Not Mandatory                             	
********************************************************************************/
int Verify(unsigned int MemoryAddr,unsigned int RAMBufferAddr,unsigned int Size){ 
	
	unsigned char data[64];
	unsigned int offset;
	unsigned char *buf=(unsigned char *)RAMBufferAddr;
	
	buf=(unsigned char *)RAMBufferAddr;
	
	while(Size>64){
		W25Q_sim_ReadData(MemoryAddr-0x90000000U,data,64);
		
		offset=0U;
		while(offset<64U){
			if(data[offset]!=*buf){
				return MemoryAddr+offset;//return Err
			}
			buf++;
			offset++;
		}
		
		MemoryAddr+=64U;
		Size-=64U;
	}
	if(Size){
		W25Q_sim_ReadData(MemoryAddr-0x90000000U,data,Size);
		
		offset=0U;
		while(offset<Size){
			if(data[offset]!=*buf){
				return MemoryAddr+offset;//return Err
			}
			buf++;
			offset++;
		}
		
		MemoryAddr+=Size;
	}
	
  return 0;
}

/*******************************************************************************
 Description :																		
 System initialization										        
 Inputs 	:																        
 				 None 																		
 outputs 	:																				
 				"1" 		: Operation succeeded						
 				"0" 		: Operation failure							
********************************************************************************/
int Init(void){ 
  
	W25Q_sim_Init();
	
  return 1;
}
